package com.feib.soeasy.dao.hibernate;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.feib.soeasy.dao.UploadFileDao;
import com.feib.soeasy.model.FormatDefinition;
import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.UploadFile;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.util.DateUtil;


/**
 * @title (#)UploadFileHibernateDao.java<br>
 * @description <br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/11/14 create by Jimmy Liu<br>
 */
@Repository("uploadFileDao")
public class UploadFileHibernateDao extends BaseHibernateDao<UploadFile, Long> implements UploadFileDao {

    @SuppressWarnings("unchecked")
    @Override
    public List<UploadFile> queryUnConfirmByUploadFile(UploadFile uploadFile)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);

        criteria.add(Restrictions.isNull("confirmStatus"));
        criteria.add(Restrictions.eq("fileStatus", UploadFile.FILE_STATUS_WAITING_CONFIRM));

        // 與上傳者是同一Group
        DetachedCriteria userDetachedCriteria = criteria.createCriteria("uploadUser");
        userDetachedCriteria.add(Restrictions.eq("group", uploadFile.getGroup()));
        
        // 轉入類別
        DetachedCriteria formatDetachedCriteria = criteria.createCriteria("formatDefinition");
        formatDetachedCriteria.add(Restrictions.eq("formatType", uploadFile.getFormatDefinition().getFormatType()));
        


        List<UploadFile> recordsList = this.getHibernateTemplate().findByCriteria(criteria);

        return recordsList;
    }

    @SuppressWarnings("unchecked")
    @Override
    public PaginatedList<UploadFile> queryPaginationByUploadFile(
                    UploadFile uploadFile, Date uploadFrom, Date uploadTo, 
                    PaginatedList<UploadFile> paginationConfig) {

        PaginatedList<UploadFile> result = new PaginatedList<UploadFile>();
        result.setPageSize(paginationConfig.getPageSize());
        result.setPageNumber(paginationConfig.getPageNumber());
        result.setSortCriterion(paginationConfig.getSortCriterion());
        result.setSortDirection(paginationConfig.getSortDirection());

        result.setFullListSize(super.countByDetachedCriteria(createDetachedCriteriaByUploadFile(uploadFile, uploadFrom, uploadTo)));

        // 筆數大於0
        if (0 < result.getFullListSize())
        {
            DetachedCriteria criteria = createDetachedCriteriaByUploadFile(uploadFile, uploadFrom, uploadTo);

            //排序
            if (null != paginationConfig.getSortCriterion())
            {
                // 由小到大
                if (PaginatedList.SORT_DIRECTION_ASC == paginationConfig.getSortDirection())
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
                else // 由大到小
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
            }


            int maxResults = result.getPageSize(); //the maximum number of results
            int firstResult = result.getFirstIndexForCurrentPage();  //the first result to retrieve, numbered from 0
            result.setPaginatedList(this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults));
        }

        return result;
    }

    /**
     * 取得單筆上傳檔案資料
     * @param uploadFilePk 上傳檔pk
     * @return 上傳檔案 UploadFile
     * @author Leo Lee
     * @since 2010/11/25
     */
    @Override
    public UploadFile getUploadFileByPk(Long uploadFilePk)
    {
        Criteria criteria = getSession().createCriteria(UploadFile.class);
        criteria.add(Restrictions.eq("uploadFilePk", uploadFilePk));
        return (UploadFile) criteria.uniqueResult();
    }


    protected DetachedCriteria createDetachedCriteriaByUploadFile(
                    UploadFile entity, Date uploadFrom, Date uploadTo)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);

        Example example = Example.create(entity);
        example.enableLike(MatchMode.START);
        criteria.add(example);

        // 上傳群組
        if (null != entity.getGroup())
        {            
            DetachedCriteria detachedCriteria = criteria.createCriteria("group");

            // PK 有值，需加入為查詢條件
            if (null != entity.getGroup().getGroupPk())
            {
                detachedCriteria.add(Restrictions.idEq(entity.getGroup().getGroupPk()));
            }

            // Group 其他查詢條件
            Example e = Example.create(entity.getGroup());
            e.enableLike(MatchMode.START);
            e.excludeZeroes();
            detachedCriteria.add(e);
        }

        // 收款類別
        if (null != entity.getFormatDefinition())
        {            
            DetachedCriteria detachedCriteria = criteria.createCriteria("formatDefinition");

            // PK 有值，需加入為查詢條件
            if (null != entity.getFormatDefinition().getFormatDefinitionPk())
            {
                detachedCriteria.add(Restrictions.idEq(entity.getFormatDefinition().getFormatDefinitionPk()));
            }

            // FormatDefinition 其他查詢條件
            Example e = Example.create(entity.getFormatDefinition());
            e.enableLike(MatchMode.START);
            e.excludeZeroes();
            detachedCriteria.add(e);
        }

        // 上傳日期
        // 有起迄
        if (null != uploadFrom && null != uploadTo)
        {
            criteria.add(Restrictions.between("uploadDate",uploadFrom, uploadTo));
        }
        else if (null != uploadFrom) // 只有起
        {
            criteria.add(Restrictions.ge("uploadDate", uploadFrom));
        }
        else if (null != uploadTo) // 只有迄
        {
            criteria.add(Restrictions.le("uploadDate", uploadTo));
        }
        else if (null != entity.getUploadDate())//單一日期
        {
            Date from = DateUtil.getBeginOfDateTime(entity.getUploadDate());
            Date to = DateUtil.getEndOfDateTime(entity.getUploadDate());
            criteria.add(Restrictions.between("uploadDate", from, to));
        }

        return criteria;
    }

    /* (non-Javadoc)
     * @see com.feib.soeasy.dao.UploadFileDao#countUploadFileByFormatDefinition(com.feib.soeasy.model.FormatDefinition)
     */
    @Override
    public int countUploadFileByFormatDefinition(FormatDefinition formatDefinition) {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);

        DetachedCriteria detachedCriteria = criteria.createCriteria("formatDefinition");
        detachedCriteria.add(Restrictions.idEq(formatDefinition.getFormatDefinitionPk()));

        return countByDetachedCriteria(criteria);
    }

    /* (non-Javadoc)
     * @see com.feib.soeasy.dao.UploadFileDao#countUploadFileByGroup(com.feib.soeasy.model.Group)
     */
    @Override
    public int countUploadFileByGroup(Group group) {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);

        DetachedCriteria detachedCriteria = criteria.createCriteria("group");
        detachedCriteria.add(Restrictions.idEq(group.getGroupPk()));

        return countByDetachedCriteria(criteria);
    }

	@SuppressWarnings("unchecked")
	@Override
	public List<UploadFile> findUploadFileByFileName(Group group,
			String fileName) {
		Criteria criteria = getSession().createCriteria(UploadFile.class);
        criteria.add(Restrictions.eq("group", group));
        criteria.add(Restrictions.eq("fileName", fileName));
        return criteria.list();
	}

}
